﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using IterationLife.ContentResources.Enums;
using IterationLife.ContentResources.Models;
using IterationLife.ContentResources.Queries;
using IterationLife.ContentResources.Repositories;
using IterationLife.Datas;
using IterationLife.Extensions.Dtos;
using IterationLife.Extensions.Helpers;
using IterationLife.PlatformBackEnd.AppServices.Contracts.ContentResources;
using IterationLife.PlatformBackEnd.AppServices.Dtos.ContentResources;
using Util;
using Util.Applications;
using Util.Datas.Queries;
using Util.Exceptions;

namespace IterationLife.PlatformBackEnd.AppServices.Impl.ContentResources
{
    /// <summary>
    /// 内容资源服务
    /// </summary>
    public class ContentResourceService : ApplicationServiceBase<ContentResource, ContentResourceDto, ContentResourceQuery>, IContentResourceService
    {
        /// <summary>
        /// 初始化内容资源服务
        /// </summary>
        /// <param name="unitOfWork">工作单元</param>
        /// <param name="contentResourceRepository">内容资源仓储</param>
        /// <param name="contentResourceCategoryRepository">内容资源分类仓储</param>
        public ContentResourceService(IApplicationUnitOfWork unitOfWork, IContentResourceRepository contentResourceRepository, IContentResourceCategoryRepository contentResourceCategoryRepository)
            : base(unitOfWork, contentResourceRepository)
        {
            ContentResourceRepository = contentResourceRepository;
            ContentResourceCategoryRepository = contentResourceCategoryRepository;
        }

        /// <summary>
        /// 内容资源仓储
        /// </summary>
        protected IContentResourceRepository ContentResourceRepository { get; set; }

        /// <summary>
        /// 内容资源分类仓储
        /// </summary>
        protected IContentResourceCategoryRepository ContentResourceCategoryRepository { get; set; }

        /// <summary>
        /// 转换为数据传输对象
        /// </summary>
        /// <param name="entity">实体</param>
        protected override ContentResourceDto ToDto(ContentResource entity)
        {
            return entity.ToDto();
        }

        /// <summary>
        /// 转换为实体
        /// </summary>
        /// <param name="dto">数据传输对象</param>
        protected override ContentResource ToEntity(ContentResourceDto dto)
        {
            return dto.ToEntity();
        }

        /// <summary>
        /// 创建查询对象
        /// </summary>
        /// <param name="param">内容资源查询实体</param>
        protected override IQueryBase<ContentResource> CreateQuery(ContentResourceQuery param)
        {
            var categoriyIds = ContentResourceCategoryRepository.GetEnabledIdsById(param.CategoriyId);
            return new Query<ContentResource>(param)
                .Filter(t => t.Title.Contains(param.Title))
                .WhereIf(t => categoriyIds.Contains(t.CategoriyId), categoriyIds.Count() > 0)
                .Filter(t => t.Type == param.Type)
                .Filter(t => t.BannerType == param.BannerType)
                .Filter(t => t.State == param.State);
        }


        /// <summary>保存前操作</summary>
        /// <param name="dto">数据传输对象</param>
        protected override void SaveBefore(ContentResourceDto dto)
        {
            switch (dto.Type)
            {
                case ContentResourceType.Article:
                    ArticleValidate(dto);
                    break;
                case ContentResourceType.Video:
                    VideoValidate(dto);
                    break;
                case ContentResourceType.Atlas:
                    AtlasValidate(dto);
                    break;
            }
            base.SaveBefore(dto);
        }

        /// <summary>
        /// 文章验证
        /// </summary>
        private void ArticleValidate(ContentResourceDto dto)
        {
            if (dto.RichText.IsEmpty())
                throw new Warning("内容不能为空");
            switch (dto.BannerType)
            {
                case ContentResourceBannerType.Single:
                    if (dto.SingleBanner == null || dto.SingleBanner.Id.IsEmpty())
                        throw new Warning("请上传封面图");
                    break;
                case ContentResourceBannerType.Three:
                    if (dto.MultiBanners == null || dto.MultiBanners.Count != 3 || dto.MultiBanners.Select(t => t.Id).Contains(Guid.Empty))
                        throw new Warning("请上传封面图");
                    break;
                case ContentResourceBannerType.Automatic:
                    var imgSrcList = HtmlHelper.GetHtmlImageUrlList(dto.RichText);
                    if (imgSrcList.Length == 0)
                        break;
                    if (imgSrcList.Length < 3)
                    {
                        dto.BannerType = ContentResourceBannerType.Single;
                        dto.SingleBanner.Id = Path.GetFileNameWithoutExtension(imgSrcList[0]).ToGuid();
                        dto.SingleBanner.Address = imgSrcList[0];
                        break;
                    }
                    dto.BannerType = ContentResourceBannerType.Three;
                    dto.MultiBanners[0].Id = Path.GetFileNameWithoutExtension(imgSrcList[0]).ToGuid();
                    dto.MultiBanners[0].Address = imgSrcList[0];
                    dto.MultiBanners[1].Id = Path.GetFileNameWithoutExtension(imgSrcList[1]).ToGuid();
                    dto.MultiBanners[1].Address = imgSrcList[1];
                    dto.MultiBanners[2].Id = Path.GetFileNameWithoutExtension(imgSrcList[2]).ToGuid();
                    dto.MultiBanners[2].Address = imgSrcList[2];
                    break;
            }
            ValidateIsRegularPublication(dto);
        }

        /// <summary>
        /// 视频验证
        /// </summary>
        private void VideoValidate(ContentResourceDto dto)
        {
            if (dto.Video == null || dto.Video.Id.IsEmpty())
                throw new Warning("请上传视频");
            switch (dto.BannerType)
            {
                case ContentResourceBannerType.Single:
                    if (dto.SingleBanner == null || dto.SingleBanner.Id.IsEmpty())
                        throw new Warning("请上传封面图");
                    break;
                case ContentResourceBannerType.Three:
                    if (dto.MultiBanners == null || dto.MultiBanners.Count != 3 || dto.MultiBanners.Select(t => t.Id).Contains(Guid.Empty))
                        throw new Warning("请上传封面图");
                    break;
                default:
                    throw new Warning("不支持该封面图方式");
            }
            ValidateIsRegularPublication(dto);
        }

        /// <summary>
        /// 图集验证
        /// </summary>
        private void AtlasValidate(ContentResourceDto dto)
        {
            if (dto.PictureDtos == null || dto.PictureDtos.Count == 0)
                throw new Warning("请添加图片集");
            for (var i = 0; i < dto.PictureDtos.Count; i++)
            {
                if (dto.PictureDtos[i].Picture == null || dto.PictureDtos[i].Picture.Id.IsEmpty())
                    throw new Warning($"请上传第{i + 1}个图集的图片");
            }
            switch (dto.BannerType)
            {
                case ContentResourceBannerType.Single:
                    if (dto.SingleBanner == null || dto.SingleBanner.Id.IsEmpty())
                        throw new Warning("请上传封面图");
                    break;
                case ContentResourceBannerType.Three:
                    if (dto.MultiBanners == null || dto.MultiBanners.Count != 3 || dto.MultiBanners.Select(t => t.Id).Contains(Guid.Empty))
                        throw new Warning("请上传封面图");
                    break;
                case ContentResourceBannerType.Automatic:
                    if (dto.PictureDtos.Count < 3)
                    {
                        dto.BannerType = ContentResourceBannerType.Single;
                        dto.SingleBanner = dto.PictureDtos[0].Picture;
                        break;
                    }
                    dto.BannerType = ContentResourceBannerType.Three;
                    dto.MultiBanners[0] = dto.PictureDtos[0].Picture;
                    dto.MultiBanners[1] = dto.PictureDtos[1].Picture;
                    dto.MultiBanners[2] = dto.PictureDtos[2].Picture;
                    break;
            }
            ValidateIsRegularPublication(dto);
        }

        /// <summary>
        /// 验证是否定时发表
        /// </summary>
        private void ValidateIsRegularPublication(ContentResourceDto dto)
        {
            if (dto.IsRegularPublication == false)
            {
                if (dto.State == ContentResourceState.Publish)
                    dto.PublicationTime = DateTime.Now;
                else
                    dto.PublicationTime = null;
                return;
            }
            if (dto.PublicationTime == null || dto.PublicationTime < DateTime.Now)
                throw new Warning("发表时间不能为空或小于当前时间");
        }

        /// <summary>保存提交前操作</summary>
        /// <param name="dto">数据传输对象</param>
        /// <param name="entity">领域实体</param>
        protected override void SaveCommitBefore(ContentResourceDto dto, ContentResource entity)
        {
            base.SaveCommitBefore(dto, entity);
            entity.SetPictures(dto.PictureDtos.Select(t => t.ToEntity()));
        }
    }
}